package org.idea.qiyu.framework.apm.agent.core.example;

import javassist.*;
import javassist.bytecode.AccessFlag;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;

/**
 * @Author linhao
 * @Date created in 1:16 下午 2021/7/18
 */
public class AgentCore {

    private static final String aimClassName = "org/idea/qiyu/framework/apm/agent/core/example/AgentDemo";

    public static void premain(String agentaArgs, Instrumentation instrumentation) {

        instrumentation.addTransformer(new ClassFileTransformer() {
            @Override
            public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
                if (className.equals(aimClassName)) {
                    System.out.println("className is :" + className);
                    ClassPool classPool = new ClassPool();
                    classPool.appendSystemPath();
                    try {
                        CtClass ctClass = classPool.get(className.replaceAll("/", "."));
                        CtMethod[] ctMethods = ctClass.getMethods();
                        for (CtMethod ctMethod : ctMethods) {
                            if (AccessFlag.isPublic(ctMethod.getModifiers()) && ctMethod.getName().equals("doTest")) {
                                CtMethod copyMethod = CtNewMethod.copy(ctMethod, ctClass, new ClassMap());
                                String newMethodName = ctMethod.getName() + "$Agent";
                                ctMethod.setName(newMethodName);
                                copyMethod.setBody("{" +
                                        "System.out.println(\"======\");\n" +
                                        newMethodName + "($$);"
                                        + "}");
                                ctClass.addMethod(copyMethod);
                            }
                        }
                        return ctClass.toBytecode();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //如果返回的是null，则不会影响原先对象所加载的字节数组
                return null;
            }
        }, true);
    }
}
